/* Original Author:  Dominick O'Dierno
 * Date: 2007   odiernod@gmail.com     --Originally intended for use with DOMercury:  http://www.odierno.com/domercury
 * Description: User interface for DOMercury configuration.
 * Basic flow:  Load current configuration to controls, 
 *              Save control values to configuration if OK button is clicked
 *              Modify Environment to reflect configuration changes
 * 
 * --CHANGELOG--
 * 
 * */

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
using DOMercury.Managers;
using DOMercury.Items;
using DOMercury.Interfaces;

namespace DOMercury.Forms
{
    public partial class OptionsForm : Form
    {
        private string nInterface = ConfigurationManager.CurrentInterface;
        public OptionsForm ()
        {
            InitializeComponent();
            lblCurrentInterface.Text = "Current Interface: " + ConfigurationManager.CurrentInterface;
            lbAliases.DataSource = AliasManager.AliasList;
            cbKeys.DataSource = Enum.GetValues(typeof(Keys));
            cbAlt.Checked = ConfigurationManager.AltKey;
            cbCtrl.Checked = ConfigurationManager.CtrlKey;
            cbShift.Checked = ConfigurationManager.ShiftKey;
            cbWindows.Checked = ConfigurationManager.WindowsKey;
            cbKeys.Text = ConfigurationManager.KeyCode.ToString();
            rbSmart.Checked = ConfigurationManager.SmartSearch;
            NUDResults.Value = IndexManager.MaximumResults;
            chkAlerts.Checked = ConfigurationManager.ShowFailAlerts;
            chkSplash.Checked = ConfigurationManager.ShowSplashScreen;
            lbInterfaces.DataSource = PluginManager.UserInterfaces;
            lbInterfaces.DisplayMember = "Name";
            btnIP.Enabled = false;
            DrawPluginsTreeView();
            if (!DOMercuryProgramFlowManager.Instance.MercuryInterface.HasOptions)
            {
                btnDisplay.Enabled = false;
            }

            //lbIItems.DisplayMember = "FullDescription";
            this.Text += " Version " + Application.ProductVersion;
        }


        private void btEdit_Click(object sender, EventArgs e)
        {
            using (AliasForm af = new AliasForm(AliasManager.AliasList[lbAliases.SelectedIndex]))
            {
                af.ShowDialog();
                if (af.DialogResult == DialogResult.OK)
                {
                    AliasManager.AliasList[lbAliases.SelectedIndex].AliasName = af.AliasName;
                    AliasManager.AliasList[lbAliases.SelectedIndex].Path = af.Path;
                    AliasManager.AliasList[lbAliases.SelectedIndex].Parameters = af.Parameters;
                    AliasManager.AliasList[lbAliases.SelectedIndex].Description = af.Description;
                    UpdatelbAliases();
                    
                }
            }
        }

        private void UpdatelbAliases()
        {
            lbAliases.DataSource = null;
            lbAliases.DataSource = AliasManager.AliasList;
        }

        private void btAdd_Click(object sender, EventArgs e)
        {
            using (AliasForm af = new AliasForm(""))
            {
                if (af.ShowDialog() == DialogResult.OK)
                {
                    AliasManager.Add(af.AliasName, af.Path, af.Parameters, af.Description);
                    UpdatelbAliases();
                }
            }
        }

        private void btDelete_Click(object sender, EventArgs e)
        {
            AliasManager.AliasList.RemoveAt(lbAliases.SelectedIndex);
            UpdatelbAliases();
        }

        private void btnOK_Click(object sender, EventArgs e)
        {

            bool reloadInterface = false;
            if (nInterface != ConfigurationManager.CurrentInterface)
            {
                ConfigurationManager.CurrentInterface = nInterface;
                reloadInterface = true;
            }
            ConfigurationManager.SmartSearch = rbSmart.Checked;
            ConfigurationManager.MaxResults = Convert.ToInt32(NUDResults.Value);
            IndexManager.MaximumResults = Convert.ToInt32(NUDResults.Value);
            IndexManager.SmartSearch = rbSmart.Checked;
            ConfigurationManager.AltKey = cbAlt.Checked;
            ConfigurationManager.CtrlKey = cbCtrl.Checked;
            ConfigurationManager.ShiftKey = cbShift.Checked;
            ConfigurationManager.WindowsKey = cbWindows.Checked;
            ConfigurationManager.KeyCode = cbKeys.Text;
            ConfigurationManager.ShowSplashScreen = chkSplash.Checked;
            ConfigurationManager.SaveCurrentConfiguration();
            try
            {
                DOMercuryProgramFlowManager.Hotkey.Enabled = false;
                DOMercuryProgramFlowManager.Hotkey.Alt = false;
                DOMercuryProgramFlowManager.Hotkey.Ctrl = false;
                DOMercuryProgramFlowManager.Hotkey.Shift = false;
                DOMercuryProgramFlowManager.Hotkey.WindowsKey = false;
                DOMercuryProgramFlowManager.Hotkey.KeyCode = (Keys)Enum.Parse(typeof(Keys), cbKeys.Text);
                DOMercuryProgramFlowManager.Hotkey.Alt = cbAlt.Checked;
                DOMercuryProgramFlowManager.Hotkey.Ctrl = cbCtrl.Checked;
                DOMercuryProgramFlowManager.Hotkey.Shift = cbShift.Checked;
                DOMercuryProgramFlowManager.Hotkey.WindowsKey = cbWindows.Checked;

                DOMercuryProgramFlowManager.Hotkey.Enabled = true;
            }
            catch
            {
                MessageBox.Show("Hotkey Change Failed: Hotkey already in use by another application.\nPlease Change Hotkey in setup and restart DOMercury.");

            }
            //if (reloadInterface)
            //{
                DOMercuryProgramFlowManager.Instance.ChangeInterface();
            //}
            this.Hide();
        }


        private void lbAliases_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            btEdit_Click(sender, new EventArgs());
        }

        private void btnReload_Click(object sender, EventArgs e)
        {
            PluginManager.LoadPlugins();
            TypeManager.ReloadPluginActions();
            IndexManager.RebuildIndex();
            DrawPluginsTreeView();
        }

        private void lbIcons_DrawItem(object sender, DrawItemEventArgs e)
        {
            KeyValuePair<string, Bitmap> line = ((KeyValuePair<string, Bitmap>)(lbIcons.Items[e.Index]));
            e.Graphics.DrawImage(line.Value, e.Bounds.Left, e.Bounds.Top, 16, 16);
            e.Graphics.DrawString(line.Key, this.Font, Brushes.Black, 16, e.Bounds.Top);

        }

        private void DrawPluginsTreeView()
        {
            tvPlugins.Nodes.Clear();
            //TreeNode plugins = new TreeNode("Plugins");
            TreeNode nIPs = new TreeNode("IItemProviders");
            TreeNode nAPs = new TreeNode("IActionProviders");
            TreeNode nPPs = new TreeNode("IParamProviders");
            TreeNode nSIs = new TreeNode("ISubIndexes");

            foreach (IItemProvider ip in PluginManager.ItemProviders)
            {
                TreeNode np = new TreeNode(ip.Name + " : " + ip.Description);
                PluginPair pp = new PluginPair();
                pp.Type = PluginType.ItemProvider;
                pp.itemProvider = ip;
                np.Tag = pp;
                nIPs.Nodes.Add(np);
            }

            foreach (IActionProvider ip in PluginManager.ActionProviders)
            {
                TreeNode np = new TreeNode(ip.Name + " : " + ip.Description);
                PluginPair pp = new PluginPair();
                pp.Type = PluginType.ActionProvider;
                pp.actionProvider = ip;
                np.Tag = pp;
                nAPs.Nodes.Add(np);
            }

            foreach (IParametersProvider ip in PluginManager.ParamProviders)
            {
                TreeNode np = new TreeNode(ip.Name + " : " + ip.Description);
                PluginPair pp = new PluginPair();
                pp.Type = PluginType.ParamProvider;
                pp.paramProvider = ip;
                np.Tag = pp;
                nPPs.Nodes.Add(np);
            }

            foreach (ISubIndex ip in PluginManager.SubIndexes)
            {
                TreeNode np = new TreeNode(ip.Name + " : " + ip.Description);
                PluginPair pp = new PluginPair();
                pp.Type = PluginType.SubIndex;
                pp.subIndex = ip;
                np.Tag = pp;
                nSIs.Nodes.Add(np);
            }
            tvPlugins.Nodes.Add(nIPs);
            tvPlugins.Nodes.Add(nAPs);
            tvPlugins.Nodes.Add(nPPs);
            tvPlugins.Nodes.Add(nSIs);
           
        }

        private void LoadIcons()
        {
            int i = 0;
            bool done = false;
            KeyValuePair<string, Bitmap> line;
            while (!done)
            {
                line = IconManager.GetPairByIndex(i);
                if (!(line.Value == null))
                {
                    lbIcons.Items.Add(line);
                    i++;
                }
                else
                {
                    done = true;
                }
            }

        }

        private void tbIcons_Enter(object sender, EventArgs e)
        {
            LoadIcons();
        }

        private void btnPriorities_Click(object sender, EventArgs e)
        {
            IndexManager.PauseRefresh = true;
            using (PriorityForm dlg = new PriorityForm())
            {
                dlg.ShowDialog();
            }
            IndexManager.SavePriorities();
            IndexManager.PauseRefresh = false;
        }

        private void btnIP_Click(object sender, EventArgs e)
        {
            if (tvPlugins.SelectedNode != null)
            {
                if (tvPlugins.SelectedNode.Tag != null)
                {

                    PluginPair pp = tvPlugins.SelectedNode.Tag as PluginPair;

                    switch (pp.Type)
                    {
                        case PluginType.ItemProvider:
                            pp.itemProvider.ShowOptions(); break;
                        case PluginType.ActionProvider:
                            pp.actionProvider.ShowOptions(); break;
                        case PluginType.ParamProvider:
                            pp.paramProvider.ShowOptions(); break;
                        default:
                            pp.subIndex.ShowOptions();
                            break;
                    }
                    IndexManager.RebuildIndex();
                }
            }
        }

       

        private void tbGeneral_Click(object sender, EventArgs e)
        {

        }

        private void btnFilters_Click(object sender, EventArgs e)
        {
            using (IndexFilters dlg = new IndexFilters())
            {
                dlg.ShowDialog();
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            
            //PluginManager.LoadPlugins();
            PluginManager.UnloadPlugins();
            TypeManager.ReloadPluginActions();
            IndexManager.RebuildIndex();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

        private void btnDisplay_Click(object sender, EventArgs e)
        {
            DOMercuryProgramFlowManager.Instance.MercuryInterface.DisplayOptions();
        }
      

        private void lbInterfaces_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            nInterface = ((IDOMercuryUserInterfaceProvider)(lbInterfaces.SelectedItem)).Name;
            lblCurrentInterface.Text = "Current Interface: " + nInterface;
        }

        private void tvPlugins_DoubleClick(object sender, EventArgs e)
        {
            btnIP_Click(sender, e);
        }

        private void tvPlugins_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (tvPlugins.SelectedNode.Tag != null)
            {
                PluginPair pp = tvPlugins.SelectedNode.Tag as PluginPair;
                switch (pp.Type)
                {
                    case PluginType.ItemProvider:
                        btnIP.Enabled = pp.itemProvider.HasOptions; break;
                    case PluginType.ActionProvider:
                        btnIP.Enabled = pp.actionProvider.HasOptions; break;
                    case PluginType.ParamProvider:
                        btnIP.Enabled = pp.paramProvider.HasOptions; break;
                    default:
                        btnIP.Enabled = pp.subIndex.HasOptions;
                        break;
                }
            }
        }     

        


    }

    class PluginPair
    {
        public IParametersProvider paramProvider;
        public IItemProvider itemProvider;
        public IActionProvider actionProvider;
        public ISubIndex subIndex;
        public PluginType Type;
    }
    enum PluginType
    {
        ItemProvider,
        ActionProvider, 
        ParamProvider, 
        SubIndex
    }

}